﻿using System;
using System.Collections.Generic;

namespace MicroCloud.Tests.DataStruct
{
    public class FixMemoryQueue<T>
    {
        private readonly int maxCount = 10;
        private readonly int count = 0;
        private readonly List<T> queue = new List<T>();
        private readonly object syncObj = new object();

        public FixMemoryQueue(int count)
        {
            this.Size = count;
        }

        public int Size { get; private set; }

        ~FixMemoryQueue()
        {
            this.queue?.Clear();
        }

        public bool PushBack(T item)
        {
            bool res = false;
            try
            {
                lock (syncObj)
                {
                    queue.Add(item);
                }
            }
            finally
            {
                res = CheckSize(() =>
                {
                    queue.RemoveRange(Size, queue.Count - Size);
                });
            }

            return res;
        }

        public bool PushFront(T item)
        {
            bool res = false;
            try
            {
                lock (syncObj)
                {
                    queue.Insert(0, item);
                }
            }
            finally
            {
                res = CheckSize(() =>
                {
                    queue.RemoveAt(0);
                });
            }

            return res;
        }

        public bool PopBack(T item)
        {
            if (queue.Count == 0) return false;

            bool result = true;
            var lastEleIdx = queue.Count - 1;
            try
            {
                queue.RemoveAt(lastEleIdx);
            }
            catch (System.Exception)
            {
                result = false;
            }

            if (result)
            {
                item = queue[lastEleIdx];
            }
            return result;
        }

        public bool PopFront(T item)
        {
            if (queue.Count == 0) return false;

            bool result = true;
            var firstEleIdx = 0;
            try
            {
                queue.RemoveAt(firstEleIdx);
            }
            catch (System.Exception)
            {
                result = false;
            }

            if (result)
            {
                item = queue[firstEleIdx];
            }
            return result;
        }

        public bool GetItem(int index, T item)
        {
            if (queue.Count < index) return false;

            bool result = true;
            try
            {
                item = queue[index];
            }
            catch (System.Exception)
            {
                result = false;
            }

            return result;
        }

        public int Count()
        {
            return queue?.Count ?? 0;
        }

        private bool CheckSize(Action removeAction)
        {
            if (queue.Count > Size) //throw new Exception($"当前队列最多{Size}个元素");
            {
                if (removeAction != null)
                {
                    removeAction.Invoke();
                }                
                return false;
            }
            return true;
        }
    }
}
